//! \file mutex.hpp
//! \brief Purewell Library Mutex Header
//! \author Yubin Lim (purewell@gmail.com)
//! \since 2008-01-25

#ifndef __PWHDR_MUTEX_HPP__
#define __PWHDR_MUTEX_HPP__

#include "types.hpp"
#include "lockobject.hpp"

namespace purewell
{

class PWMutexAttribute;

//! \brief Mutex
class PWAPI PWMutex : public PWLockObject
{
public:

	//! \brief Lock.
	void lock(void);

	//! \brief Lock test.
	//! If unlocking state, lock.
	//! \return On success, true.
	bool lockTest(void);

	//! \brief Lock test(time limited).
	//! If unlocked state, wait for unlocking and try to lock.
	//! \return On success, true.
	bool lockTimeLimit(size_t msec);

	//! \brief Unlock.
	void unlock(void);

public:
	//! \brief Create mutex.
	//! \param[in] type Mutex Type.
	//! \param[in] pshared Process shared.
	//! \return On success, mutex pointer or NULL.
	static PWMutex* create(int type, bool pshared = false);

	//! \brief Create mutex.
	//! \param[in] pattr Mutex attribution.
	//! \return On success, mutex pointer or NULL.
	static PWMutex* create(const PWMutexAttribute* pattr = NULL);

	//! \brief Release mutex object.
	//! \param[in] lock Mutex object pointer.
	static void release(PWMutex* lock);

private:
	explicit PWMutex();
	virtual ~PWMutex();
};

//! \brief Mutex Attribution.
class PWAPI PWMutexAttribute : public PWThreadObject
{
public:
	//! \brief Create mutex attribution.
	//! \return On success, mutex attribution pointer or NULL.
	static PWMutexAttribute* create(void);

	//! \brief Release mutex attribution.
	//! \param[in] obj Mutex attribution pointer to release.
	static void release(PWMutexAttribute* obj);

public:
	//! \brief Set mutex type.
	//! \param[in] type Mutex type.
	//! \return On success, true.
	bool setType(int type = PWMUTEX_DEFAULT);

	//! \brief Get mutex type.
	//! \param[out] type Mutex type.
	//! \return On success, true.
	bool getType(int& type) const;

	//! \brief Set process shared.
	//! \param[in] pshared Process shared.
	//! \return On success, true.
	bool setShared(bool pshared);

	//! \brief Get process shared.
	//! \param[in] pshared Process shared.
	//! \return On success, true.
	bool getShared(bool& pshared) const;

private:
	explicit PWMutexAttribute();
	virtual ~PWMutexAttribute();
};

};//namespace purewell

#endif//!__PWHDR_MUTEX_HPP__

